#include "guiterm.hpp"
#ifndef REMOTEHOST_HPP
#define REMOTEHOST_HPP
#include "RPC.hpp"

class ServerConnection
	:public QObject,
	 public RemoteHost
{
	Q_OBJECT;
public:
	ServerConnection(BackendConnection *connection);
	ServerConnection(ServerConnection *parent, int jobid, StreamSender *inputSender);
	
	bool isLocal();
	
	void disconnected(bool error, string message);
	
	void attachSession(Session *session);
	Session *getSession();
	
	int newJob();
	void attachJob(RemoteJob *job);
	RemoteJob *getJob(int id);
	
	void attachFileView(int id, FileView *fileView);
	
	int newTransferId();
	void attachDownloader(int id, FileRequest *downloader);
	void removeDownloader(int id);
	FileRequest *getDownloader(int id);
	
	void attachUploader(FileUploader *uploader);
	void removeUploader(FileUploader *uploader);
	FileUploader *getAnyUploader();
	
	void beginOutput(int job);
	void programOutput(int job, const char *data, int len);
	void outputFinished(int hob);
	
	void expectLsResponse(int id, FileView *view);
	FileView *getPendingFileView(int id);
	
	void sendData(int len, const char *data);
	
public slots:
	void idle();
	
protected:
	StreamSender *inputSender;
	ServerConnection *parentHost;
	BackendConnection *connection;
	Session *session;
	
	bool local;
	int maxJobid;
	int parentJobid;
	map<int, ServerConnection*> children;
	map<int, RemoteJob*> programs;
	int maxTransferId;
	map<int, FileRequest*> downloaders;
	map<int, FileView*> pendingFileViews;
	
	vector<FileUploader*> uploaders;
	int lastUploader;
};

Session *getSession(RemoteHost *host, const RPCParams *params);
RemoteJob *getJob(RemoteHost *host, const RPCParams *params);
FileRequest *getRequest(RemoteHost *host, const RPCParams *params);
FileView *getPendingFileView(RemoteHost *host, const RPCParams *params);

class ProgramOutputHandler
	:public QObject,
	 public StreamReceiver
{
	Q_OBJECT
public:
	ProgramOutputHandler(ServerConnection *host, const RPCParams *params);
	void recv(int len, const char *data);
	void onClose();
	
protected:
	ServerConnection *host;
	int job;
};

#endif
